package com.pug.web.login;

import com.pug.annotation.EnableNoToken;
import com.pug.annotation.SaveLogonMessage;
import com.pug.bo.KssUserBo;
import com.pug.constant.PugContants;
import com.pug.dto.MessageDto;
import com.pug.pojo.KssUser;
import com.pug.pojo.WeiXinData;
import com.pug.result.ex.KsdBusinessException;
import com.pug.service.idwork.IdWorkService;
import com.pug.service.message.MessageServiceMq;
import com.pug.service.user.UserServiceImpl;
import com.pug.threadlocal.UserThreadLocal;
import com.pug.utils.fn.asserts.Vsserts;
import com.pug.utils.pwd.DesUtils;
import com.pug.vo.KssUserVo;
import com.pug.vo.LoginByPwdVo;
import com.pug.vo.LogoutVo;
import com.pug.web.BaseController;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.UUID;


/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2022/3/16$ 23:56$
 */
@RestController
@RequiredArgsConstructor
public class PassportLoginController extends BaseController implements PugContants {

    private final UserServiceImpl userService;
    private final IdWorkService idWorkService;
    @Resource
    MessageServiceMq messageServiceMq;
    @Resource
    StringRedisTemplate stringStringRedisTemplate;
    @Resource
    RedisTemplate<String,KssUser> redisTemplateUser;
    @SaveLogonMessage //登录保存用户信息
    @Transactional(propagation = Propagation.REQUIRED) //加上事务
    @PostMapping("/passport/login")
    public KssUserBo logined(@RequestBody  KssUserVo kssUser) {
        // 1: 接受用户提交用户手机和短信
        String inputPhone = kssUser.getPhone();
        String inputSmsCode = kssUser.getSmscode();
        // 2: 获取redis缓存中的存储短信
        String cacheSmsCode = redisOperator.get(PUG_XQ_LOGIN_SMS_CODE + inputPhone);
        if(cacheSmsCode==null){
            throw new KsdBusinessException(602,"验证码已经失效");
        }
//        Vsserts.isEmptyEx(cacheSmsCode, "短信已经失效");
        // 3: 对比短信码是否正确
        if (!cacheSmsCode.equalsIgnoreCase(inputSmsCode)) {
            throw new KsdBusinessException(602, "你输入短信证码有误!");
        }
        //删除验证码
        redisTemplateUser.delete(PUG_XQ_LOGIN_SMS_CODE + inputPhone);
        // 4：开始进行业务的处理
        KssUser dbUser = userService.getByPhone(DesUtils.encrypt(inputPhone));
        // 如果dbUser，说明没有注册
        if (Vsserts.isNull(dbUser)) {
            // 开始注册
            dbUser = new KssUser();

            dbUser.setPhone(DesUtils.encrypt(inputPhone));
            dbUser.setIdcode(idWorkService.nextShort());
            dbUser.setNickname("小伴");
            dbUser.setPassword("");
            dbUser.setAvatar("http://121.43.183.166:9000/lqx/50a52204-a5c0-4074-9330-6786221334e0.jpg");
            dbUser.setSex(2);
            dbUser.setCountry("中国");
            dbUser.setProvince("");
            dbUser.setCity("");
            dbUser.setDistrict("");
            dbUser.setDescription("Ta什么都没有留下...");
            dbUser.setBgImg("https://scpic.chinaz.net/files/pic/pic9/202007/apic26488.jpg");
            dbUser.setStatus(1);

            //异步保存注册信息(mongodb)
            MessageDto messageDto=new MessageDto();
            messageDto.setAvatar("http://121.43.183.166:9000/lqx/50a52204-a5c0-4074-9330-6786221334e0.jpg");
            messageDto.setIcon("");
            messageDto.setMsgcontent("恭喜您，注册成功！");
            messageDto.setNickname("小伴");
            messageDto.setMsgtype(1);
            messageDto.setTitle("注册通知");
            messageServiceMq.pushMessageSave(messageDto);
            //向mysql保存用户信息
            userService.saveOrUpdate(dbUser);
        }

        // 5: 存在就返回
        KssUserBo kssUserBo = new KssUserBo();
        BeanUtils.copyProperties(dbUser, kssUserBo);
        // 6: 生成一个uuid代表token
        String uuid = UUID.randomUUID().toString();
        //向redis插入一个token
        stringStringRedisTemplate.opsForValue().set(PUG_XQ_LOGIN_USER_TOKEN+dbUser.getId(),uuid);
        //向redis加入用户的信息，方便以后的使用(无需查询MySQL)
        redisTemplateUser.opsForValue().set(PUG_XQ_LOGIN_USER_INFO+dbUser.getId(),dbUser);

        KssUser kssUser1 = UserThreadLocal.get();
        kssUserBo.setToken(uuid);
        return kssUserBo;
    }


    //退出登录
    @EnableNoToken(value = true)
    @PostMapping("/passport/logout")
    public boolean logout(@RequestBody LogoutVo logoutVo){
           try {
               String token=logoutVo.getToken();
               String userId=logoutVo.getUserId();
               //删除token
               redisTemplateUser.delete(PUG_XQ_LOGIN_USER_TOKEN+userId);
               //删除redis中的用户信息
               redisTemplateUser.delete(PUG_XQ_LOGIN_USER_INFO+userId);

           }catch (Exception e){
               throw new KsdBusinessException(601,"退出失败");
           }
            return true;
    }
    //账号密码登录
    @EnableNoToken(value = true)
    @PostMapping("/passport/loginpwd")
    public KssUserBo loginByPwd(@RequestBody LoginByPwdVo loginByPwdVo){
        String phone = DesUtils.decrypt(loginByPwdVo.getPhone());
        KssUser kssUser = userService.selectByPhone(phone);
        if(kssUser==null){
            throw new KsdBusinessException(600,"账号密码错误");
        }
        String decrypt = DesUtils.decrypt(loginByPwdVo.getPassword());
        if(!kssUser.getPassword().equals(decrypt)){
            throw new KsdBusinessException(600,"账号密码错误");
        }
        KssUserBo kssUserBo = new KssUserBo();
        BeanUtils.copyProperties(kssUser, kssUserBo);
        //token
        String token=UUID.randomUUID().toString();
        stringStringRedisTemplate.opsForValue().set(PUG_XQ_LOGIN_USER_TOKEN+kssUser.getId(),token);
        redisTemplateUser.opsForValue().set(PUG_XQ_LOGIN_USER_INFO+kssUser.getId(),kssUser);
        kssUserBo.setToken(token);
        return kssUserBo;
    }
    @EnableNoToken(true)
    @PostMapping("/passport/wxlogin/code")
    public KssUserBo loginByWeiXin(@RequestBody WeiXinData weiXinData){
        userService.getOpenId(weiXinData);
        return null;
    }
}
